<template>
  <div
    class="table-card-container animate__animated"
    :class="[visible ? 'animate__fadeIn' : 'animate__fadeOut']"
  >
    <a-spin :spinning="loading">
      <div ref="gantt" class="gantt-container" v-if="isShow"></div>
      <a-empty v-else />
    </a-spin>
  </div>
</template>

<script>
import gantt from "dhtmlx-gantt";
import "dhtmlx-gantt/codebase/dhtmlxgantt.css";
import { flatTreeData } from "@/utils/util.js";
import {
  getListByParentIdTable,
  getListByParentIdDraft,
  getListByParentIdHistory,
} from "@/api/progressManage";
export default {
  inject: ["versionSource", "conditionsSource", "treeItemSource", "firstIndex"],
  props: {
    visible: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      ganttData: {
        data: [],
        links: [],
      },
      loading: false,
      //
      isShow: true,
    };
  },
  mounted() {
    // if (!this.isShow) {
    //   return;
    // }
    // this.$nextTick(() => {
    //   window.addEventListener("resize", () => {
    //     let { componentKey } = this.firstIndex();
    //     if (componentKey == "ganttCard") {
    //       if (this.ganttData.data.length > 0) {
    //         this.isShow = true;
    //         this.$nextTick(() => {
    //           this.initGantt();
    //         });
    //       } else {
    //         this.isShow = false;
    //       }
    //     }
    //   });
    // });
  },
  methods: {
    getListByParentIdTable,
    getListByParentIdDraft,
    getListByParentIdHistory,
    getData() {
      let { tenantCode, orgCode, name, defaultTime } = this.conditionsSource();
      let { uuid = "", status = "" } = this.versionSource();
      let apiUrl = "";
      if (status == 4) {
        //正式
        apiUrl = "getListByParentIdTable";
      } else if (status == 5) {
        //历史
        apiUrl = "getListByParentIdHistory";
      } else {
        //草稿
        apiUrl = "getListByParentIdDraft";
      }
      if (!this.treeItemSource()?.uuid) {
        this.ganttData.data = [];
        return;
      }
      this.loading = true;
      this[apiUrl]({
        showAll: 1,
        versionId: uuid,
        parentId: this.treeItemSource()?.uuid ?? "",
        orgCode,
        ganttChart: 1,
        name,
        startDate: defaultTime?.[0] ?? "",
        endDate: defaultTime?.[1] ?? "",
        proCode: tenantCode,
      })
        .then((res) => {
          let { data } = res;
          this.ganttData.data = data?.chartList ?? [];
          this.ganttData.links = data?.preList ?? [];

          if (this.ganttData.data.length > 0) {
            this.isShow = true;
            this.$nextTick(() => {
              this.initGantt();
            });
          } else {
            this.isShow = false;
          }
        })
        .catch(() => {
          this.ganttData.data = [];
          this.ganttData.links = [];
        })
        .finally(() => {
          this.loading = false;
        });
    },
    //初始化-甘特图
    initGantt() {
      // 清空之前的配置
      gantt.clearAll();
      // 设置中文
      gantt.i18n.setLocale("cn");
      //自定义左侧 头部列的内容
      gantt.config.columns = [
        {
          name: "id",
          label: "序号",
          align: "center",
          width: "50",
          template: function(obj) {
            return obj.sortIndex;
          },
        },
        {
          name: "text", //在tasks.data中定义的属性数据，add为例外,add为新增数据项触发gantt新增弹窗，显示为一个加
          label: "任务名称", //标记描述
          tree: true, //相关列应显示树
          width: "200", //宽度，可写max _width min_width
          align: "left", //文字格式
          resize: true, //布尔值，可以拉伸内容宽度
          template: function(obj) {
            return obj.text;
          },
        },
        {
          name: "duration",
          label: "周期",
          align: "center",
          width: "50",
          template: function(obj) {
            return obj.duration;
          },
        },
        {
          name: "start_date",
          label: "计划开始时间",
          align: "center",
          width: "100",
          template: function(obj) {
            return obj.start_date;
          },
        },
        {
          name: "end_date",
          label: "计划完成时间",
          align: "center",
          width: "100",
          template: function(obj) {
            return obj.end_date;
          },
        },
      ];
      //时间轴图表中-日期展示格式
      let { ganttView = 1 } = this.firstIndex();
      switch (ganttView) {
        //日视图
        case 1:
          gantt.config.scales = [
            { unit: "year", step: 1, format: "%Y年-%M" },
            { unit: "day", format: "%d" },
          ];
          break;

        //周视图
        case 2:
          gantt.config.scales = [
            { unit: "year", step: 1, format: "%Y年-%M" },
            { unit: "week", format: "第%w周" },
          ];
          break;

        //月视图
        case 3:
          gantt.config.scales = [
            { unit: "year", step: 1, format: "%Y年" },
            { unit: "month", step: 1, format: "%M" },
          ];
          break;

        //季度视图
        case 4:
          gantt.config.scales = [
            { unit: "year", step: 1, format: "%Y年" },
            { unit: "quarter", step: 1, format: quarterLabel },
          ];
          break;
        default:
          break;
      }
      function quarterLabel(date) {
        var month = date.getMonth();
        var q_num;

        if (month >= 9) {
          q_num = "四";
        } else if (month >= 6) {
          q_num = "三";
        } else if (month >= 3) {
          q_num = "二";
        } else {
          q_num = "一";
        }
        return "第" + q_num + "季度";
      }
      // 鼠标经过打开 tooltip 提示
      gantt.plugins({
        tooltip: true,
        // 拖动图
        drag_timeline: true,
      });
      gantt.templates.tooltip_text = function(start, end, task) {
        return `
          <div style="font-weight: 400;font-size: 16px;color: #2B2C30;font-family: Microsoft YaHei;margin-bottom: 10px;"> ${
            task.text
          }</div>
          <div style="font-weight: 400;font-size: 14px;color: #666666;font-family: Microsoft YaHei;margin-bottom: 8px;">计划开始时间：${gantt.templates.tooltip_date_format(
            start
          )}</div>
          <div style="font-weight: 400;font-size: 14px;color: #666666;font-family: Microsoft YaHei;margin-bottom: 8px;">计划结束时间：${gantt.templates.tooltip_date_format(
            end
          )}</div>
           <div style="font-weight: 400;font-size: 14px;color: #666666;font-family: Microsoft YaHei;margin-bottom: 8px;">周期：${
             task.duration
           }</div>
              `;
      };
      //滚动条布局
      gantt.config.scroll_size = 9;
      gantt.config.layout = {
        css: "gantt_container",
        cols: [
          {
            width: 500,
            rows: [
              {
                view: "grid",
                scrollX: "gridScroll",
                scrollable: true,
                scrollY: "scrollVer",
              },
              { view: "scrollbar", id: "gridScroll", group: "horizontal" },
            ],
          },
          { resizer: true, width: 1 },
          {
            rows: [
              { view: "timeline", scrollX: "scrollHor", scrollY: "scrollVer" },
              { view: "scrollbar", id: "scrollHor", group: "horizontal" },
            ],
          },
          { view: "scrollbar", id: "scrollVer" },
        ],
      };
      //取消右边表格进度条显示与拖动
      gantt.config.show_progress = false;
      //用户可以通过拖拽调整行高
      gantt.config.resize_rows = true;
      //时间轴图表中  设置图例高度
      gantt.config.bar_height = 25;
      // 只读模式：打开后不可以操作甘特图
      gantt.config.readonly = true;
      // 初始化甘特图  可以通过ref挂载 或者 id选择器挂载
      gantt.init(this.$refs.gantt);
      // 渲染数据
      gantt.parse(this.ganttData);
      //建议每一次修改配置项调用一次render方法
      gantt.render();
    },

    //
    clearData() {
      this.isShow = false;
      this.ganttData = {
        data: [],
        links: [],
      };
    },

    //处理数据格式
    dealWithData() {
      this.ganttData = {
        data: [],
        links: [],
      };
      this.treeData.forEach((item) => {
        this.ganttData.data.push({
          //自定义排序
          sortIndex: item.index,
          //任务的唯一标识符
          id: item.id,
          //任务的名称。
          text: item.name,
          //任务的开始日期，可以是一个字符串或者一个 Date 对象。
          start_date: this.reverseDate(item.planStartTime),
          //任务的结束日期，可以是一个字符串或者一个 Date 对象。
          end_date: this.reverseDate(item.planEndTime),
          //任务的持续时间，以天为单位。如果 end_date 和 duration 都提供了，duration 会被忽略。
          duration: item.duration,
          //任务的进度，以百分比表示。
          progress: 1,
          //是否展开当前任务的子任务。如果不提供，默认为 true。
          open: true,
          //用于设置任务的状态。状态可以是任何自定义值，例如 "in progress"、"completed"、"cancelled" 等等。在 Gantt 图中，任务的状态可以通过任务条颜色、边框、文本样式等 visulization 属性进行自定义渲染，以便用户更直观地了解任务状态的变化。可以在 Gantt 文档中的 Visualization 属性部分了解有关自定义任务状态可视化的更多信息
          // state:''
        });
      });
      let flatData = flatTreeData(this.treeData, "childList");
      flatData.forEach((item) => {
        this.ganttData.data = this.pushUniqueElement(this.ganttData.data, item);
      });
    },

    //追加子元素
    pushUniqueElement(array, newElement) {
      const existingElement = array.find((el) => el.id === newElement.id);
      if (!existingElement) {
        array.push({
          sortIndex: newElement.index,
          id: newElement.id,
          text: newElement.name,
          start_date: this.reverseDate(newElement.planStartTime),
          end_date: this.reverseDate(newElement.planEndTime),
          duration: newElement.duration,
          progress: 1,
          open: true,
          parent: newElement.parentId,
        });
      }
      return array;
    },

    //时间反转
    reverseDate(dateStr) {
      var parts = dateStr.split("-");
      if (parts.length === 3) {
        return parts.reverse().join("-");
      } else {
        return this.$message.info(
          "Invalid date format. Please use 'YYYY-MM-DD'."
        );
      }
    },

    //追加序号
    addIndexToTree(treeData) {
      let index = 1;
      function traverse(node) {
        node.index = index++;
        if (node.childList) {
          node.childList.forEach((child) => {
            traverse(child);
          });
        }
      }
      treeData.forEach((node) => {
        traverse(node);
      });
      return treeData;
    },

    //不能删除
    setPage() {},
  },
  destroyed() {
    // window.removeEventListener("resize", () => {});
  },
};
</script>

<style lang="less" scoped>
.table-card-container {
  height: 100%;
  display: flex;
  flex-direction: column;
  padding-top: 10px;
  user-select: none;
  position: relative;
  /deep/.ant-spin {
    width: 100%;
    height: 100%;
    max-height: 100%;
  }

  .gantt-container {
    height: 100%;
    width: 100%;

    /deep/.gantt_layout_content {
      .gantt_task {
        .gantt_data_area {
          .gantt_task_bg {
            .gantt_task_row {
              border-bottom: 0;
              .gantt_task_cell {
                background-color: rgba(235, 240, 255, 0.5);
              }
              &:last-of-type {
                border-bottom: 1px solid #ebebeb;
              }
              &.gantt_selected {
                background: #f0f8ff;
              }
            }
          }
        }
      }
      .gantt_grid_data .gantt_row.gantt_selected {
        background: #f0f8ff;
      }
      .gantt_grid_data .gantt_row:hover {
        background: #f0f8ff;
      }
      .gantt_hor_scroll {
        border-top: 1px solid #e9ebee;
        border-bottom: 1px solid #e9ebee;
        &::-webkit-scrollbar {
          /*滚动条整体样式*/
          width: 8px;
          height: 8px;
        }
        &::-webkit-scrollbar-thumb {
          /*滚动条里面小方块*/
          border-radius: 8px;
          background: #dbdbdb;
        }

        &::-webkit-scrollbar-track {
          /*滚动条里面轨道*/
          border-radius: 8px;
        }
      }
    }
  }
  /deep/.ant-empty {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
  }
}
</style>
<style lang="less">
.gantt_tooltip {
  z-index: 999;
}
</style>
